package com.mall.project.gs.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mall.common.core.asserts.ApiAssert;
import com.mall.common.core.cons.StatusCons;
import com.mall.common.core.enums.ErrorCodeEnum;
import com.mall.common.core.model.response.ApiResponses;
import com.mall.common.core.model.supers.SuperController;
import com.mall.common.core.utils.TreeUtils;
import com.mall.common.security.annotation.PreAuth;
import com.mall.project.gs.model.dto.GoodsCategoryDTO;
import com.mall.project.gs.model.dto.GoodsCategoryTreeDTO;
import com.mall.project.gs.model.entity.GoodsCategory;
import com.mall.project.gs.model.parm.GoodsCategoryPARM;
import com.mall.project.gs.service.IGoodsCategoryService;
import com.mall.project.info.service.IPhotoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类表 前端控制器
 * </p>
 *
 * @author Sam
 * @since 2021-10-11
 */
@Api(tags = {"商品分类"})
@RestController
@RequestMapping("/goodsCategory")
public class GoodsCategoryRestController extends SuperController {

    @Autowired
    private IGoodsCategoryService goodsCategoryService;
    @Autowired
    private IPhotoService photoService;

    @PreAuth
    @ApiOperation("查询商品分类")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "商品名称 模糊", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "是否显示（1：显示；0：隐藏）", paramType = "query"),
            @ApiImplicitParam(name = "delFlag", value = "是否显示（1：正常；0：删除）", paramType = "query"),
    })
    @GetMapping("/page")
    public ApiResponses<IPage<GoodsCategory>> page(@RequestParam(value = "name", required = false) String name,
                                                   @RequestParam(value = "status", required = false) Integer status,
                                                   @RequestParam(value = "delFlag", required = false) Integer delFlag) {
        LambdaQueryWrapper<GoodsCategory> wrapper = Wrappers.<GoodsCategory>lambdaQuery()
                .like(StringUtils.isNotBlank(name), GoodsCategory::getName, name)
                .eq(Objects.nonNull(status), GoodsCategory::getStatus, status)
                .eq(Objects.nonNull(delFlag), GoodsCategory::getDelFlag, delFlag);
        IPage<GoodsCategory> iPage = goodsCategoryService.page(this.getPage(), wrapper);
        IPage<GoodsCategoryDTO> dtoiPage = iPage.convert(e -> e.convert(GoodsCategoryDTO.class));
        for (GoodsCategoryDTO record : dtoiPage.getRecords()) {
            record.setPicList(photoService.listPhoto(record.getId(), "商品分类"));
        }
        return success(iPage);
    }


    @PreAuth
    @ApiOperation("单条查询商品分类")
    @GetMapping("/{id}")
    public ApiResponses<GoodsCategoryDTO> getById(@PathVariable("id") String id) {
        GoodsCategory entity = goodsCategoryService.getById(id);
        ApiAssert.notNull(ErrorCodeEnum.BAD_SELECT_FAILURE, entity);
        GoodsCategoryDTO dto = entity.convert(GoodsCategoryDTO.class);
        dto.setPicList(photoService.listPhoto(dto.getId(), "商品分类"));
        return success(dto);
    }

    @PreAuth
    @ApiOperation("查询商品分类")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "delFlag", value = "是否显示（1：正常；0：删除）", paramType = "query"),
    })
    @GetMapping("/trees")
    public ApiResponses<List<GoodsCategoryTreeDTO>> treeList(@RequestParam(value = "delFlag", required = false) Integer delFlag) {
        List<GoodsCategoryTreeDTO> treeSource = goodsCategoryService.list(Wrappers.<GoodsCategory>lambdaQuery()
                .eq(Objects.nonNull(delFlag), GoodsCategory::getDelFlag, delFlag)
                .orderByAsc(GoodsCategory::getOrderNum))
                .stream().map(e -> {
                    GoodsCategoryTreeDTO dto = e.convert(GoodsCategoryTreeDTO.class);
                    dto.setPicList(photoService.listPhoto(dto.getId(), "商品分类"));
                    return dto;
                }).collect(Collectors.toList());
        List<GoodsCategoryTreeDTO> treeList = treeSource.stream().filter(e -> !(Objects.nonNull(e.getPid()) && !"0".equals(e.getPid())))
                .map(e -> TreeUtils.findChildren(e, treeSource)).collect(Collectors.toList());
        return success(treeList);
    }

    @PreAuth
    @ApiOperation("新增商品分类")
    @PostMapping
    public ApiResponses<Void> create(@RequestBody @Validated(value = GoodsCategoryPARM.Create.class) GoodsCategoryPARM gcp) {
        GoodsCategory goodsCategory = gcp.convert(GoodsCategory.class);
        ApiAssert.isTrue(ErrorCodeEnum.BAD_ADD_FAILURE, goodsCategoryService.save(goodsCategory));
        return success();
    }

    @PreAuth
    @ApiOperation("修改分类")
    @PutMapping
    public ApiResponses<Void> updateById(@RequestBody GoodsCategoryPARM gcp) {
        String id = gcp.getId();
        ApiAssert.isFalse(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("上级分类不能是自己"), Objects.equals(id, gcp.getPid()));
        ApiAssert.isFalse(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("该分类包含未作废的子分类"),
                Objects.equals(StatusCons.DISABLE, gcp.getDelFlag()) &&
                        goodsCategoryService.count(Wrappers.<GoodsCategory>lambdaQuery()
                                .eq(GoodsCategory::getPid, id).eq(GoodsCategory::getStatus, StatusCons.NORMAL)) > 0);
        GoodsCategory update = gcp.convert(GoodsCategory.class);
        ApiAssert.isTrue(ErrorCodeEnum.BAD_UPDATE_FAILURE, goodsCategoryService.updateById(update));
        return success();
    }


    @PreAuth
    @ApiOperation("删除商品分类")
    @DeleteMapping("/{id}")
    public ApiResponses<Void> deleteById(@PathVariable("id") String id) {
        GoodsCategory goodsCategory = goodsCategoryService.getById(id);
        ApiAssert.notNull(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("不存在此商品分类"), goodsCategory);
        int count = goodsCategoryService.count(Wrappers.<GoodsCategory>lambdaQuery()
                .eq(GoodsCategory::getPid, id).eq(GoodsCategory::getDelFlag, StatusCons.NORMAL));
        ApiAssert.isFalse(ErrorCodeEnum.INTERNAL_SERVER_ERROR.convert("存在下级商品分类,不允许删除"), count > 0);
        //修改商品分类状态
        ApiAssert.isTrue(ErrorCodeEnum.BAD_DELETE_FAILURE, goodsCategoryService.update(Wrappers.<GoodsCategory>lambdaUpdate()
                .set(GoodsCategory::getDelFlag, StatusCons.DISABLE).eq(GoodsCategory::getId, id)));
        return success();
    }

    @PreAuth
    @ApiOperation("修改商品分类状态")
    @PutMapping("/changeStatus")
    public ApiResponses<Void> changeStatus(@RequestBody @Validated(GoodsCategoryPARM.ChangeStatus.class) GoodsCategoryPARM gcp) {
        GoodsCategory goodsCategory = new GoodsCategory();
        goodsCategory.setId(gcp.getId());
        goodsCategory.setStatus(gcp.getStatus());
        ApiAssert.isTrue(ErrorCodeEnum.BAD_UPDATE_FAILURE, goodsCategoryService.updateById(goodsCategory));
        return success();
    }
}

